package com.it.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.it.reggie.common.R;
import com.it.reggie.dto.SetmealDto;
import com.it.reggie.entity.Category;
import com.it.reggie.entity.Setmeal;
import com.it.reggie.entity.SetmealDish;
import com.it.reggie.service.CategoryService;
import com.it.reggie.service.SetmealDishService;
import com.it.reggie.service.SetmealService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

//套餐管理
@RestController
@RequestMapping("/setmeal")
@Slf4j
@Api(tags = "套餐相关接口")//反映在swagger(运行之后访问http://localhost:8080/doc.html#/home)文档
public class SetmealController {//添加套餐功能，操作的主表还是套餐表Setmeal，其次要操作关联关系表SetmealDish

    @Autowired
    private CategoryService categoryService;

    @Autowired
    private SetmealService setmealService;

    @Autowired
    private SetmealDishService setmealDishService;

//除了有套餐普通的属性外，还有setmealDishes(当前的套餐对应的都有哪些菜品)，所以参数不能是setmeal,要用setmealDto(扩展了setmealDishes属性)
    @PostMapping//新增套餐//因为提交过来的是json数据
    @CacheEvict(value = "setmealCache", allEntries = true)//表示要清理setmealCache下面所有的缓存数据
    @ApiOperation(value = "新增套餐接口")//反映在swagger(运行之后访问http://localhost:8080/doc.html#/home)文档
    public R<String> save(@RequestBody SetmealDto setmealDto){
        log.info("套餐信息：{}",setmealDto);//向套餐表和套餐和菜品关系表插入数据

        setmealService.saveWithDish(setmealDto);

        return R.success("新增套餐成功");
    }

    //套餐分页查询

    @GetMapping("/page")//                       套餐名称
    @ApiOperation(value = "套餐分页查询接口")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "页码", required = true),
            @ApiImplicitParam(name = "pageSize", value = "每页记录数", required = true),
            @ApiImplicitParam(name = "name", value = "套餐名称", required = false)
    })
    public R<Page> page(int page, int pageSize, String name) {
        //分页构造器
        Page<Setmeal> pageInfo = new Page<>(page, pageSize);//分页的列表数据会在这里封装进Page的List<T> records集合里面？？？？？
        System.out.println("看看这个pageInfo的records的尺寸："+pageInfo.getRecords().size());
        System.out.println("看看这个pageInfo的records的内容"+pageInfo.getRecords().toString());
        Page<SetmealDto> dtoPage = new Page<>();

        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        //添加查询条件，根据name进行like模糊查询
        queryWrapper.like(name != null, Setmeal::getName, name);
        //添加排序条件，根据更新时间降序排列
        queryWrapper.orderByDesc(Setmeal::getUpdateTime);

        setmealService.page(pageInfo, queryWrapper);//查完之后，pageInfo对象里相关的属性都已经附上值了
        //对象拷贝
        BeanUtils.copyProperties(pageInfo,dtoPage,"records");
//records(在page里面)不需要(因为泛型不一样(为什么，先记住。。)，pageInfo的是Setmeal，dtoPage的是SetmealDto)拷贝
// (记录，分页的列表数据会封装在List<T> records集合里面)？？？？？？？
//records没拷过去，需要自己去设置他的值
        List<Setmeal> records = pageInfo.getRecords();//把records，单独get出来处理
//在前端页面，列表数据通常是通过异步请求从后端获取的。一般情况下，后端会提供一个接口（API）来返回列表数据。
//前端通过发送请求到该接口，获取数据并将其存储到页面的 "records" 中。
        List<SetmealDto> list = records.stream().map((item) -> {
            SetmealDto setmealDto = new SetmealDto();
            //分类id，get到每个categoryId，就可以查询数据库，拿分类名称
            Long categoryId = item.getCategoryId();
            //根据分类id查询分类对象，此时需要categoryService
            Category category = categoryService.getById(categoryId);
            if(category!=null){//拿得到之后
                String categoryName = category.getName();//最终目标，分类名称
                setmealDto.setCategoryName(categoryName);//终极目标，给setmealDto填充categoryName值
                //现在这个新new出来的setmealDto的其它属性还是空的，继续把套餐实体的其它普通属性拷到setmealDto里面
                System.out.println("setmealDto里有什么"+setmealDto.getCategoryName()+setmealDto.getName()+setmealDto.getId()+setmealDto.getCategoryId()+setmealDto.getPrice());
                BeanUtils.copyProperties(item,setmealDto);//对象拷贝
                System.out.println("setmealDto怎么样了"+setmealDto.getCategoryName()+setmealDto.getName()+setmealDto.getId()+setmealDto.getCategoryId()+setmealDto.getPrice());
            }
            return setmealDto;
        }).collect(Collectors.toList());//转成list<setmealDto>集合

        //单独给dtoPage设置records(list类型)的值，把刚才的list集合给进去
        dtoPage.setRecords(list);
        System.out.println("再次看看这个pageInfo的records的尺寸"+pageInfo.getRecords().size());
        System.out.println("再次看看这个pageInfo的records的内容"+pageInfo.getRecords().toString());
        return R.success(dtoPage);
        //直接返回pageInfo不好,因为pageInfo里的泛型是Setmeal，而Setmeal只存了categoryId，而套餐管理页面要显示的是categoryName
    }

    //@RequestParam注解用于绑定名为"ids"的请求参数到方法的List<Long>类型的参数上。
    //这意味着当发送请求时，可以通过提供名为"ids"的参数来传递一个或多个Long类型的值。
    //例如，如果发送一个GET请求到"/delete?ids=1&ids=2&ids=3"，其中ids参数的值为1、2和3，
    // 那么这个方法将会接收到一个包含这些值的List<Long>参数。
    @ApiOperation(value = "套餐删除接口")
    @DeleteMapping  //单个id和多个id都可以装
    @CacheEvict(value = "setmealCache", allEntries = true)//表示要清理setmealCache下面所有的缓存数据
    public R<String> delete(@RequestParam List<Long> ids){
        log.info("ids：{}",ids);
//删除套餐时，对应的关联关系也要删除
        setmealService.removeWithDish(ids);
        return R.success("套餐数据删除成功");
    }
    //根据条件查询套餐数据
    @ApiOperation(value = "套餐条件查询套餐接口")
    @GetMapping("/list")//setmeal/list?categoryId=？？？&status=1/0并不是json格式数据，不能用@RequestBody
    @Cacheable(value = "setmealCache", key = "#setmeal.categoryId + '_' + #setmeal.status")//缓存
    public R<List<Setmeal>> list(Setmeal setmeal){
        LambdaQueryWrapper<Setmeal> queryWrapper = new LambdaQueryWrapper<>();
        //!=空再去添加条件/手机端主页面的商务套餐和儿童套餐请求的是setmeal/list?categoryId=？？？&status=1/0
        queryWrapper.eq(setmeal.getCategoryId()!=null,Setmeal::getCategoryId,setmeal.getCategoryId());
        queryWrapper.eq(setmeal.getStatus()!=null,Setmeal::getStatus,setmeal.getStatus());
        queryWrapper.orderByDesc(Setmeal::getUpdateTime);

        List<Setmeal> list = setmealService.list(queryWrapper);

        return R.success(list);//返回结果R需要实现序列化接口，否则无法缓存
    }
}
